home *** CD-ROM | disk | FTP | other *** search
- /* TStats --------------------------------------------------------
- *
- * Accumulate, calculate and display timing data.
- *
- * Copyright (c) 1993 Bill Karsh.
- * All rights reserved.
- *
- */
-
-
- #pragma options( honor_register, !assign_registers )
- #pragma options( !check_ptrs )
-
-
- #include "TStats.h"
- #include "LongArrayStats.h"
- #include "PlotLongArray.h"
- #include <math.h>
- #include <stdio.h>
-
-
- #define WMargins 5
- #define TitleBarHt 18
- #define TextLines 3
- #define UseSameScales 1
-
- // glue and shorthands
-
- #define Alloc( type, n ) \
- (type*)NewPtr( sizeof(type) * (n) )
-
- #define Kill( q ) \
- if( ts->q.data ) DisposePtr( ts->q.data )
-
- #define Limits( q ) \
- LongArrayMinMax( ts->q.data, ts->q.N, \
- &ts->q.min, &ts->q.max )
-
- #define Plot( q, r, str ) \
- PlotLongArray( ts->q.data, ts->q.N, \
- 0, ts->q.N, ts->q.min, ts->q.max, \
- &ts->r, str )
-
- #define Histo( h, q ) \
- LongArrayBin( ts->q.data, ts->q.N, \
- ts->q.min, ts->q.max, \
- ts->h.data, ts->h.N )
-
- #define SameScales( u, v ) \
- if( ts->u.min < ts->v.min ) \
- ts->v.min = ts->u.min; \
- else \
- ts->u.min = ts->v.min; \
- \
- if( ts->u.max > ts->v.max ) \
- ts->v.max = ts->u.max; \
- else \
- ts->u.max = ts->v.max;
-
-
- #define MaxBin( q, h, w ) \
- LongArrayGetMaxBin( ts->q.data, ts->q.N, \
- ts->q.min, ts->q.max, \
- ts->h.data, ts->h.N, \
- ts->w.data, &ts->w.N )
-
- #define NewPort() \
- GetPort( &oldPort ); SetPort( ts->w )
-
- #define Print( h, str, val, dig ) \
- MoveTo( h, v ); \
- *s = sprintf( s+1, "%."#dig"f", val ); \
- DrawString( str ); DrawString( s )
-
-
- static pTS gTS;
-
-
-
-
-
-
- /* LayoutWindow --------------------------------------------------
- *
- * Arrange data areas of window.
- *
- */
-
- static void LayoutWindow( void )
- {
- register pTS ts = gTS;
- Rect r;
- FontInfo fi;
- short lineHt, pad;
-
- r = ts->w->portRect;
- InsetRect( &r, WMargins, WMargins );
-
- GetFontInfo( &fi );
- lineHt = fi.ascent + fi.descent + fi.leading;
-
- #define t1 ts->statsR1
- #define t2 ts->statsR2
- #define p1 ts->plotR1
- #define p2 ts->plotR2
-
- // left and right
-
- t1.left = p1.left = p2.left = r.left;
- t2.right = p1.right = p2.right = r.right;
-
- t1.right = t1.left + (r.right - t1.left - WMargins)/2;
- t2.left = t1.right + WMargins;
-
- // top and bottom
-
- t1.top = t2.top = r.top;
- t1.bottom = t2.bottom = t1.top + TextLines * lineHt + 2;
-
- p1.top = t1.bottom + WMargins;
- p1.bottom = p1.top + (r.bottom - p1.top - WMargins)/2;
-
- p2.top = p1.bottom + WMargins;
- p2.bottom = r.bottom;
-
- #undef t1
- #undef t2
- #undef p1
- #undef p2
- }
-
-
- /* AllocateArrays ------------------------------------------------
- *
- * Allocate data arrays.
- *
- */
-
- static void AllocateArrays( long nData, long nBins )
- {
- register pTS ts = gTS;
-
- ts->maxRaw = nData;
- ts->bins1.N = ts->bins2.N = nBins;
-
- ts->acc1 = ts->raw1.data = Alloc( long, nData );
- ts->acc2 = ts->raw2.data = Alloc( long, nData );
-
- ts->bins1.data = Alloc( long, nBins+1 );
- ts->bins2.data = Alloc( long, nBins+1 );
-
- ts->work1.data = ts->work2.data = nil;
-
- ts->raw1.N = ts->raw2.N = 0;
- }
-
-
- /* TSInit --------------------------------------------------------
- *
- * Allocate window and init structures.
- *
- */
-
- void TSInit( Rect *rGlobal, long nData, long nBins )
- {
- register pTS ts;
- GrafPtr oldPort;
- Rect *r, R;
-
- gTS = ts = Alloc( TSRec, 1 );
-
- if( !(r = rGlobal) ) { // auto size window
- R = screenBits.bounds;
- InsetRect( &R, 3, 3 );
- R.top += MBarHeight + TitleBarHt;
- R.bottom >>= 1;
- r = &R;
- }
-
- ts->w = NewWindow( nil, r, nil, true,
- noGrowDocProc, (WindowPtr)-1, false, 0L );
-
- NewPort();
- TextFont( geneva );
- TextSize( 9 );
-
- LayoutWindow();
-
- AllocateArrays( nData, nBins );
-
- ts->combRawSd = 0.0;
-
- SetPort( oldPort );
- }
-
-
- /* TSDispose -----------------------------------------------------
- *
- * Deallocate.
- *
- */
-
- void TSDispose( void )
- {
- register pTS ts = gTS;
-
- if( !ts ) return;
-
- if( ts->w ) DisposeWindow( ts->w );
-
- Kill( raw1 );
- Kill( raw2 );
- Kill( work1 );
- Kill( work2 );
- Kill( bins1 );
- Kill( bins2 );
-
- DisposePtr( ts );
- }
-
-
- /* TSAccumulate --------------------------------------------------
- *
- * Add data to arrays.
- *
- */
-
- void TSAccumulate( long time1, long time2 )
- {
- register pTS ts = gTS;
-
- if( ts->raw1.N < ts->maxRaw && time1 >= 0 ) {
- *ts->acc1++ = time1;
- ++ts->raw1.N;
- }
-
- if( ts->raw2.N < ts->maxRaw && time2 >= 0 ) {
- *ts->acc2++ = time2;
- ++ts->raw2.N;
- }
- }
-
-
- /* TSRawPlots ----------------------------------------------------
- *
- * Display plots of accumulated raw data.
- *
- */
-
- void TSRawPlots( void )
- {
- register pTS ts = gTS;
- GrafPtr oldPort;
-
- if( !ts->raw1.N ) return;
-
- NewPort();
-
- Limits( raw1 );
- Limits( raw2 );
-
- #if UseSameScales == 1
- SameScales( raw1, raw2 );
- #endif
-
- Plot( raw1, plotR1, "\pRaw Time1" );
- Plot( raw2, plotR2, "\pRaw Time2" );
-
- SetPort( oldPort );
- }
-
-
- /* TSStats -------------------------------------------------------
- *
- * Calculate and display statistics for arrays.
- *
- * sourceType is one of the defined constants {kRaw, kWork}.
- *
- */
-
- void TSStats( long sourceType )
- {
- register pTS ts = gTS;
- GrafPtr oldPort;
- Rect *r;
- double mean1, mean2, sd1, sd2, z1, z2;
- long *data1, *data2;
- long N1, N2;
- FontInfo fi;
- Byte s[36];
- short lineHt, h1, h2, h3, v;
-
- if( sourceType == kRaw ) {
- data1 = ts->raw1.data;
- data2 = ts->raw2.data;
- N1 = ts->raw1.N;
- N2 = ts->raw2.N;
- r = &ts->statsR1;
- }
- else {
- data1 = ts->work1.data;
- data2 = ts->work2.data;
- N1 = ts->work1.N;
- N2 = ts->work2.N;
- r = &ts->statsR2;
- }
-
- if( !N1 ) return;
-
- NewPort();
-
- ForeColor( blackColor );
- EraseRect( r );
- FrameRect( r );
-
- GetFontInfo( &fi );
- h1 = r->left + 2;
- h3 = (r->right - r->left)/3;
- h2 = r->left + h3;
- h3 += h2;
- v = r->top + fi.ascent + 1;
-
- lineHt = fi.ascent + fi.descent + fi.leading;
-
- LongArrayMeanDev( data1, N1, &mean1, &sd1 );
- LongArrayMeanDev( data2, N2, &mean2, &sd2 );
-
- if( sourceType == kRaw ) {
- Print( h1, "\pmean1 = ", mean1, 0 );
- Print( h2, "\pmean2 = ", mean2, 0 );
- }
- else {
- Print( h1, "\pmode1 = ", mean1, 0 );
- Print( h2, "\pmode2 = ", mean2, 0 );
- }
-
- v += lineHt;
-
- Print( h1, "\psd1 = ", sd1, 2 );
- Print( h2, "\psd2 = ", sd2, 2 );
-
- v += lineHt;
-
- z1 = mean1 - mean2;
- Print( h1, "\pdiff = ", z1, 0 );
-
- z2 = z1 / mean2 * 100.0;
- Print( h2, "\prel diff = ", z2, 2 );
- DrawChar( '%' );
-
- if( sourceType == kRaw ) {
-
- ts->combRawSd = z2 =
- sqrt( sd1*sd1/ts->raw1.N + sd2*sd2/ts->raw2.N );
-
- if( z2 > 0.0 )
- z1 = fabs( z1 ) / z2;
- else
- z1 = 0.0;
- Print( h3, "\pZ = ", z1, 2 );
- }
- else {
- if( ts->combRawSd > 0.0 )
- z1 = fabs( z1 ) / ts->combRawSd;
- else
- z1 = 0.0;
- Print( h3, "\pZ = ", z1, 2 );
- }
-
- SetPort( oldPort );
- }
-
-
- /* TSRawHistos ---------------------------------------------------
- *
- * Calculate and display plots of freq data.
- *
- */
-
- void TSRawHistos( void )
- {
- register pTS ts = gTS;
- GrafPtr oldPort;
-
- if( !ts->raw1.N ) return;
-
- NewPort();
-
- Histo( bins1, raw1 );
- Histo( bins2, raw2 );
-
- Limits( bins1 );
- Limits( bins2 );
-
- #if UseSameScales == 1
- SameScales( bins1, bins2 );
- #endif
-
- Plot( bins1, plotR1, "\pFreq Time1" );
- Plot( bins2, plotR2, "\pFreq Time2" );
-
- SetPort( oldPort );
- }
-
-
- /* TSFilterMode --------------------------------------------------
- *
- * Calculate and display plots of data only in
- * max bin ( the mode ).
- * Places this separated data in work structures.
- *
- * sourceType is one of the defined constants {kRaw, kWork}.
- *
- * Returns true if max == min for newly filtered data,
- * else returns false.
- *
- */
-
- Boolean TSFilterMode( long sourceType )
- {
- register pTS ts = gTS;
- GrafPtr oldPort;
-
- if( !ts->raw1.N ) return true;
-
- NewPort();
-
- if( !ts->work1.data )
- ts->work1.data = Alloc( long, ts->raw1.N );
-
- if( !ts->work2.data )
- ts->work2.data = Alloc( long, ts->raw1.N );
-
- if( sourceType == kRaw ) {
- MaxBin( raw1, bins1, work1 );
- MaxBin( raw2, bins2, work2 );
- }
- else {
- if( ts->work1.max != ts->work1.min )
- MaxBin( work1, bins1, work1 );
-
- if( ts->work2.max != ts->work2.min )
- MaxBin( work2, bins2, work2 );
- }
-
- Limits( work1 );
- Limits( work2 );
-
- Histo( bins1, work1 );
- Histo( bins2, work2 );
-
- Limits( bins1 );
- Limits( bins2 );
-
- Plot( bins1, plotR1, "\pMost Freq Time1" );
- Plot( bins2, plotR2, "\pMost Freq Time2" );
-
- SetPort( oldPort );
-
- return (ts->work1.max == ts->work1.min &&
- ts->work2.max == ts->work2.min);
- }
-
-
-